/** Object.assign方法用于对象的合并 ，将源对象（source）的所有可枚举属性，复制到目标对象（target）。*/

/*const target = { a: 1 };

const source1 = { b: 2 };
const source2 = { c: 3 };

Object.assign(target, source1, source2);
console.log(target); // {a:1, b:2, c:3}*/




/** 注意，如果目标对象与源对象有同名属性，或多个源对象有同名属性，则后面的属性会覆盖前面的属性。*/
/*const target = { a: 1, b: 1 };

const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };

Object.assign(target, source1, source2);
console.log(target); // {a:1, b:2, c:3}*/



/** 如果只有一个参数，Object.assign会直接返回该参数。*/
/*const obj = {a: 1};
console.log(Object.assign(obj) === obj); // true*/



/** 如果该参数不是对象，则会先转成对象，然后返回。*/
/*console.log(Object.assign(2)); // [Number: 2]
/!*
Number {2}
__proto__: Number
  constructor: ƒ Number()
  toExponential: ƒ toExponential()
  toFixed: ƒ toFixed()
  toLocaleString: ƒ toLocaleString()
  toPrecision: ƒ toPrecision()
  toString: ƒ toString()
  valueOf: ƒ valueOf()
  __proto__: Object
   [[PrimitiveValue]]: 0
  [[PrimitiveValue]]: 2
*!/
console.log(Object.assign(2)+1); // 3
console.log(typeof Object.assign(2)); // "object"*/



/** 由于undefined和null无法转成对象，所以如果它们作为参数，就会报错。*/
/*Object.assign(undefined) // 报错
Object.assign(null) // 报错*/
//TypeError: Cannot convert undefined or null to object
//     at Function.assign (<anonymous>)



/** 如果非对象参数出现在源对象的位置（即非首参数），那么处理规则有所不同。首先，这些参数都会转成对象，如果无法转成对象，就会跳过。
 * 这意味着，如果undefined和null不在首参数，就不会报错。*/
/*let obj = {a: 1};
console.log(Object.assign(obj, undefined) === obj); // true
console.log(Object.assign(obj, null) === obj); // true
console.log(obj); // { a: 1 }*/

//其他类型的值（即数值、字符串和布尔值）不在首参数，也不会报错。但是，除了字符串会以数组形式，拷贝入目标对象，其他值都不会产生效果。
/*const v1 = 'abc';
const v2 = true;
const v3 = 10;

const obj = Object.assign({}, v1, v2, v3);
console.log(obj); // { "0": "a", "1": "b", "2": "c" }*/
//上面代码中，v1、v2、v3分别是字符串、布尔值和数值，结果只有字符串合入目标对象（以字符数组的形式），数值和布尔值都会被忽略。
//这是因为只有字符串的包装对象，会产生可枚举属性。

/*Object(true) // {[[PrimitiveValue]]: true}
Object(10)  //  {[[PrimitiveValue]]: 10}
Object('abc') // {0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"}*/
//↑
// 上面代码中，布尔值、数值、字符串分别转成对应的包装对象，可以看到它们的原始值都在包装对象的内部属性 [[PrimitiveValue]]上面，这个属性是不会被Object.assign拷贝的。只有字符串的包装对象，会产生可枚举的实义属性，那些属性则会被拷贝。


/** 属性名为 Symbol 值的属性，也会被Object.assign拷贝。*/
console.log(Object.assign({a: 'b'}, {[Symbol('c')]: 'd'}));
// { a: 'b', Symbol(c): 'd' }
